#include<iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

using namespace std;
const int BufferSize=1024;

char pwd[BufferSize];

//命令表
int argc;
char* argv[128];

//环境变量表
char* envriment[128];

//最后的退出信息

int lastcode=0;

string getName()
{
    string name=getenv("USER");
   return name.empty()?"none":name;
}

string getHost()
{
    string host=getenv("HOSTNAME");
    return host.empty() ? "none":host;
}

std:: string getPwd()
{
   if( getcwd(pwd,sizeof(pwd))==NULL)
   {
       return "none";
   }
   return pwd;

}


void PrintCommintLine()
{
    char buffer[1024];
    snprintf(buffer,sizeof(buffer),"[%s@%s %s]#",getName().c_str(),getHost().c_str(),getPwd().c_str());
    string ps=(string)buffer;

    printf("%s",ps.c_str());

    fflush(stdout);
}

bool GetCommintLine(char buffer[])
{
   char*re= fgets(buffer,BufferSize,stdin);
   if(re)
   {
       buffer[strlen(buffer)-1]=0;
       if(strlen(buffer)==0)return false;

       return true;
   }
   return false;
}

void AnalyaseCommitLine(char buffer[])
{
    memset(argv,0,argc);
    argc=0;
    argv[argc++]=strtok(buffer," ");
    while((bool)(argv[argc++]=strtok(NULL," ")));
    argc--;
 }


void debug(char* argv[])
{
    for(int i=0;i<argc;i++)
    {
        printf("%s\n",argv[i]);
    }
}

bool ExcuteCommint()
{
    int pd=fork();
    if(pd<0)
    {
        exit(1);
    }
    else if(pd==0)
    {
        execvp(argv[0],argv);
    }

   int status;
   pid_t rid= waitpid(pd,&status,0);
   if(rid>0)
   {
       return true;
   }
   return false;
}

bool CheckCommint()
{
    if(strcmp(argv[0],"cd")==0)
    {
        if(argc==2)
        {
        chdir(argv[1]);
        return true;
        }
        lastcode=1;
        return true;
    }
    else if(strcmp(argv[0],"env")==0)
    {
        //这里我们需要自己维护一张环境变量表进行打印
        int i=0;
        while(envriment[i])
        {
            printf("%s\n",envriment[i]);
            i++;
        }
        return true;
    }
    else if(strcmp(argv[0],"export")==0)
    {
        //我们需要导入到自己的环境变量中
        int index=0;
        while(envriment[index++]);
        string str;
        for(int i=1;i<argc;i++)
        {
            str+=argv[i];
        }
        envriment[index++]=(char*)str.c_str();
        envriment[index]=NULL;
        return true;
    }
    else if(strcmp(argv[0],"echo")==0)
    {
        //打印上一次的退出消息并覆盖
        if(argv[1][1]=='$')
        {
            if(argv[1][2]=='?')
            {
                printf("%d\n",lastcode);
                lastcode=0;
            }
        }
        return true;
    }

    return false;
}
void InitEnv()
{
    
    extern char** environ;
    int index=0;
    while(environ[index])
    {
        //这里需要自己开辟空间
        envriment[index]=new char[strlen(environ[index]+1)];
        strncpy(envriment[index],environ[index],strlen(environ[index]));
        index++;
    }
    envriment[index]=NULL;
}
int main()
{
    //初始化环境变量表
    //InitEnv();
    char buffer[BufferSize];
    while(1)
    {
    PrintCommintLine();
    //命令提示符
    //获取用户命令
    if(!GetCommintLine(buffer))
    {
        continue;
    }

    //分析命令,对命令进行分割
    AnalyaseCommitLine(buffer);
    //执行命令前先检查是不是内建命令
    if(CheckCommint())
    {
        continue;
    }
    //执行命令
    ExcuteCommint();
    }
    return 0;
}
